﻿using System;
using System.ComponentModel;

namespace UIT.ScrumTool.Client.Utilities.TaskGridView
{
    public class TaskEditTable : TaskGV, IEditableObject
    {
        private readonly object[] m_oldValues = new object[11];
        private bool m_isBeingEdited;

        public TaskEditTable()
        {
        }

        public TaskEditTable(string id, string subject, string description, float estimateStoryPoint, int importance,
                             int operatorId,
                             int sprintId, int projectId, float height, int color, float estimatedDuration)
            : base(
                id, subject, description, estimateStoryPoint, importance, operatorId, sprintId, projectId, height, color, estimatedDuration
                )
        {
        }

        #region Implementation of IEdtableObject

        public void BeginEdit()
        {
            if (m_isBeingEdited)
                return;
            if (!string.IsNullOrEmpty(subject))
            {
                m_isBeingEdited = true;
                m_oldValues[0] = id;
                m_oldValues[1] = subject;
                m_oldValues[2] = description;
                m_oldValues[3] = estimateStoryPoint;
                m_oldValues[4] = importance;
                m_oldValues[5] = operatorId;
                m_oldValues[6] = sprintId;
                m_oldValues[7] = projectId;
                m_oldValues[8] = height;
                m_oldValues[9] = color;
                m_oldValues[10] = estimatedDuration;
                //ham update
            }
        }

        public void CancelEdit()
        {
            if (!m_isBeingEdited)
            {
                id = (string) m_oldValues[0];
                subject = (string) m_oldValues[1];
                description = (string) m_oldValues[2];
                estimateStoryPoint = (float) m_oldValues[3];
                importance = (int) m_oldValues[4];
                operatorId = (int) m_oldValues[5];
                sprintId = (int) m_oldValues[6];
                projectId = (int) m_oldValues[7];
                height = (float) m_oldValues[8];
                color = (int) m_oldValues[9];
                estimatedDuration = (float) m_oldValues[10];
                m_isBeingEdited = false;
                if (m_containingList != null)
                {
                    if (((TaskBindingListComplete) m_containingList).LastAddedComposer == this) //AddNew
                    {
                        // If the element is coming from an AddNew and EndEdit has not been called yet,
                        // we have to remove the row from our containing list.
                        m_containingList.Remove(this);
                    }
                    else
                    {
                        // Advise the grid of the modification via the ListChanged event of the IBindingList interface.
                        InvokeListChanged(new ListChangedEventArgs(ListChangedType.ItemChanged,
                                                                   m_containingList.IndexOf(this)));
                    }
                }
            }
        }

        public void EndEdit()
        {
            if (string.IsNullOrEmpty(subject))
            {
                if (m_containingList != null)
                {
                    if (((TaskBindingListComplete) m_containingList).LastAddedComposer == this) //AddNew
                    {
                        // If the element is coming from an AddNew and EndEdit has not been called yet,
                        // we have to remove the row from our containing list.
                        m_containingList.Remove(this);
                    }
                }
            }
            if ((!m_isBeingEdited))
            {
                return;
            }
            // There is nothing to do with the temporary values that we kept
            // since the values are already committed. Therefore, we clear
            // the temporary object array.
            Array.Clear(m_oldValues, 0, m_oldValues.Length);
            m_isBeingEdited = false;

            if (m_containingList != null)
            {
                if (((TaskBindingListComplete) m_containingList).LastAddedComposer == this) // AddNew
                {
                    // If the element is coming from an AddNew and EndEdit was never called before,
                    // we have to advise the grid by raising a ListChanged with ListChangedType.ItemAdded a second time.
                    InvokeListChanged(new ListChangedEventArgs(ListChangedType.ItemAdded, m_containingList.IndexOf(this)));
                    ((TaskBindingListComplete) m_containingList).LastAddedComposer = null;
                }
            }
        }

        #endregion

        protected override void InvokeListChanged(ListChangedEventArgs e)
        {
            if (!m_isBeingEdited)
            {
                if (m_containingList != null)
                    ((TaskBindingListComplete) m_containingList).InvokeOnListChanged(e);
            }
        }
    }
}